import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Input, Button, Select, Typography, Card, Spin, Modal, App, Form } from 'antd';
import { useParams, useNavigate } from 'react-router-dom';
import VariableTextArea from '../components/VariableTextArea';
import { get, post, postWithResponse } from '../utils/request';

const { Title, Text } = Typography;

const VARIABLE_TYPES = [
  { label: '文本', value: 'text' },
  { label: '多行文本', value: 'multi_text' },
  { label: '单选', value: 'radio' },
  { label: '多选', value: 'options' },
];

type VariableType = 'text' | 'multi_text' | 'radio' | 'options';
interface VariableConfig {
  name: string;
  type: VariableType;
  options?: string[];
  description?: string;
}

const extractVariables = (content: string): string[] => {
  const result: string[] = [];
  let i = 0;
  while (i < content.length) {
    if (content[i] === '$' && content[i + 1] === '{') {
      let start = i + 2;
      let stack = 1;
      let j = start;
      while (j < content.length && stack > 0) {
        if (content[j] === '{') stack++;
        else if (content[j] === '}') stack--;
        j++;
      }
      if (stack === 0) {
        result.push(content.slice(start, j - 1));
        i = j;
      } else {
        break;
      }
    } else {
      i++;
    }
  }
  return Array.from(new Set(result));
};

const paramListToVariables = (paramList: any[]): VariableConfig[] => {
  return (paramList || []).map(param => ({
    name: param.label,
    type: param.type as VariableType,
    options: Array.isArray(param.values) ? param.values : [],
    description: param.hintText || '',
  }));
};

const TemplateEdit: React.FC = () => {
  const { message: messageApi } = App.useApp();
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [content, setContent] = useState('');
  const [variables, setVariables] = useState<VariableConfig[]>([]);
  const [isComposing, setIsComposing] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [sceneOptions, setSceneOptions] = useState<{label: string, value: number}[]>([]);
  const [sceneLoading, setSceneLoading] = useState(false);
  const [name, setName] = useState('');
  const [templateDesc, setTemplateDesc] = useState('');
  const [sceneId, setSceneId] = useState<number | undefined>(undefined);
  const [previewLoading, setPreviewLoading] = useState(false);
  const [previewVisible, setPreviewVisible] = useState(false);
  const [previewResult, setPreviewResult] = useState<string[]>([]);
  const [form] = Form.useForm();
  const hasFetchedScenes = useRef(false);

  // 拉取场景下拉
  useEffect(() => {
    const fetchSceneList = async () => {
      // 如果已经获取过场景列表，就不再获取
      if (hasFetchedScenes.current) return;
      hasFetchedScenes.current = true;

      try {
        setSceneLoading(true);
        const res = await get('/api/admin/template/scene/list');
        if (res && Array.isArray(res.list)) {
          setSceneOptions(res.list.map((item: any) => ({ label: item.sceneName, value: item.id })));
        } else {
          setSceneOptions([]);
        }
      } catch (error) {
        setSceneOptions([]);
      } finally {
        setSceneLoading(false);
      }
    };

    fetchSceneList();
  }, []); // 空依赖数组，只在组件挂载时执行一次

  // 拉取详情并回显
  useEffect(() => {
    if (id) {
      setLoading(true);
      setError('');
      get('/api/admin/template/get', { id })
        .then((res: any) => {
          if (res) {
            setName(res.name || '');
            setTemplateDesc(res.templateDesc || '');
            setSceneId(res.sceneId);
            setContent(res.content || '');
            setVariables(paramListToVariables(res.paramList));
            form.setFieldsValue(res);
          } else {
            setError('获取模版详情失败');
          }
        })
        .catch(() => setError('获取模版详情失败'))
        .finally(() => setLoading(false));
    }
  }, [id, form]);

  // 只在 isComposing 结束后同步变量（新建时）
  useEffect(() => {
    if (!isComposing) {
      const names = extractVariables(content);
      setVariables(prev => {
        // 变量名完全同步，顺序与内容区一致
        return names.map((name, idx) => {
          // 尝试迁移原有配置（类型、选项）
          const old = prev.find(v => v.name === name)
            || prev[idx]; // 若只是改名，迁移同位置的类型和选项
          return old && old.name !== name
            ? { ...old, name }
            : old || { name, type: 'text', options: [] };
        });
      });
    }
  }, [content, isComposing]);

  // 变量类型切换
  const handleTypeChange = (name: string, type: VariableType) => {
    setVariables(vars => vars.map(v => {
      if (v.name !== name) return v;
      if (type === 'radio' || type === 'options') {
        // 若无选项，自动补一个默认选项
        return { ...v, type, options: (v.options && v.options.length > 0) ? v.options : ['选项1'] };
      } else {
        return { ...v, type, options: [] };
      }
    }));
  };

  // 选项增删改
  const handleOptionChange = (name: string, idx: number, value: string) => {
    setVariables(vars => vars.map(v => v.name === name ? { ...v, options: v.options?.map((opt, i) => i === idx ? value : opt) } : v));
  };
  const handleAddOption = (name: string) => {
    setVariables(vars => vars.map(v => v.name === name ? { ...v, options: [...(v.options || []), `选项${(v.options?.length || 0) + 1}`] } : v));
  };
  const handleRemoveOption = (name: string, idx: number) => {
    setVariables(vars => vars.map(v => v.name === name ? { ...v, options: v.options?.filter((_, i) => i !== idx) } : v));
  };

  // 预览
  const handlePreview = useCallback(async () => {
    try {
      setPreviewLoading(true);
      const paramList = variables.map(v => ({
        hintText: v.description || '',
        label: v.name,
        required: false,
        type: v.type,
        values: v.type === 'radio' || v.type === 'options' ? v.options || [] : [],
      }));
      const paramMap: Record<string, string> = {};
      variables.forEach(v => { paramMap[v.name] = v.name; });
      const body = {
        content,
        paramList,
        paramMap,
        name,
        templateDesc,
        sceneId,
        id: id ? Number(id) : undefined,
      };
      const res = await post('/api/admin/prompt/preview', body);
      
      if (Array.isArray(res)) {
        setPreviewVisible(true);
        setPreviewResult(res);
      } else if (res.success && Array.isArray(res.data)) {
        setPreviewVisible(true);
        setPreviewResult(res.data);
      } else {
        messageApi.error('预览失败');
      }
    } catch (error) {
      messageApi.error('预览失败');
    } finally {
      setPreviewLoading(false);
    }
  }, [content, name, templateDesc, sceneId, id, variables, messageApi]);

  // 保存
  const handleSubmit = async () => {
    try {
      const values = await form.validateFields();
      setLoading(true);
      
      const paramList = variables.map(v => ({
        hintText: v.description || '',
        label: v.name,
        required: false,
        type: v.type,
        values: v.type === 'radio' || v.type === 'options' ? v.options || [] : [],
      }));

      const data = {
        ...values,
        content,
        paramList,
        name,
        templateDesc,
        sceneId,
        id: id ? Number(id) : undefined,
      };
      
      const res = await postWithResponse('/api/admin/template/save', data);
      if (res.success) {
        messageApi.success('发布成功！');
        navigate('/template-manager');
      } else {
        messageApi.error(res.errorMsg || '发布失败');
      }
    } catch (error) {
      messageApi.error('保存失败');
    } finally {
      setLoading(false);
    }
  };

  // 分组渲染变量区
  const renderVariableRows = (variables: VariableConfig[]): React.ReactNode => {
    return (
      <div style={{ width: '100%' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead>
            <tr style={{ borderBottom: '1px solid #f0f0f0' }}>
              <th style={{ padding: '6px', textAlign: 'left', width: '14%' }}>变量名</th>
              <th style={{ padding: '6px', textAlign: 'left', width: '8%' }}>类型</th>
              <th style={{ padding: '6px', textAlign: 'left', width: '28%' }}>填写提示</th>
              <th style={{ padding: '6px', textAlign: 'left', width: 'auto' }}>选项</th>
            </tr>
          </thead>
          <tbody>
            {variables.map(v => (
              <tr key={v.name} style={{ borderBottom: '1px solid #f0f0f0' }}>
                <td style={{ padding: '6px', textAlign: 'left' }}>
                  <Text strong style={{ display: 'block', textAlign: 'left' }}>{v.name}</Text>
                </td>
                <td style={{ padding: '6px' }}>
                  <Select
                    value={v.type}
                    options={VARIABLE_TYPES}
                    style={{ width: '100%' }}
                    size="small"
                    onChange={type => handleTypeChange(v.name, type as VariableType)}
                  />
                </td>
                <td style={{ padding: '6px' }}>
                  <Input
                    placeholder="请输入填写提示"
                    value={v.description}
                    onChange={e => setVariables(vars => vars.map(var_ => var_.name === v.name ? { ...var_, description: e.target.value } : var_))}
                    style={{ width: '100%' }}
                    size="small"
                  />
                </td>
                <td style={{ padding: '6px', width: v.type === 'radio' || v.type === 'options' ? 'auto' : 'auto', minWidth: v.type === 'radio' || v.type === 'options' ? '200px' : 'auto' }}>
                  {(v.type === 'radio' || v.type === 'options') ? (
                    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, width: '100%' }}>
                      {v.options?.map((opt, idx) => (
                        <div key={idx} style={{ 
                          display: 'flex', 
                          alignItems: 'center', 
                          gap: 2, 
                          background: '#fafbfc', 
                          borderRadius: 3, 
                          padding: '1px 3px',
                          marginBottom: 4,
                          flex: '0 0 auto'
                        }}>
                          <Input
                            value={opt}
                            onChange={e => handleOptionChange(v.name, idx, e.target.value)}
                            style={{ width: 'auto', minWidth: 50, maxWidth: 80, fontSize: 12 }}
                            size="small"
                            placeholder={`选项${idx + 1}`}
                          />
                          <Button 
                            size="small" 
                            danger 
                            onClick={() => handleRemoveOption(v.name, idx)} 
                            disabled={(v.options?.length || 0) <= 1} 
                            style={{ padding: '0 2px', fontSize: 12, height: 20, minWidth: 20 }}
                          >
                            删
                          </Button>
                        </div>
                      ))}
                      <Button 
                        size="small" 
                        type="dashed" 
                        onClick={() => handleAddOption(v.name)} 
                        style={{ height: 20, fontSize: 12, padding: '0 4px', marginBottom: 4 }}
                      >
                        +
                      </Button>
                    </div>
                  ) : (
                    <Text type="secondary" style={{ display: 'inline-block' }}>-</Text>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  };

  return (
    <div style={{ 
      background: '#fff', 
      padding: '0px 8px',
      height: '100vh',
      position: 'relative',
      overflow: 'hidden'
    }}>
      <Title level={5} style={{ textAlign: 'left', margin: '12px 0', fontWeight: 600, fontSize: 18 }}>{id ? '编辑模版' : '新增模版'}</Title>
      <Spin spinning={loading} tip="加载中...">
        {error && <div style={{ color: 'red', marginBottom: 16 }}>{error}</div>}
        {/* 顶部表单区 */}
        <Card style={{ marginBottom: 24 }} bodyStyle={{ padding: 24 }}>
          <Form layout="inline" form={form}>
            <Form.Item label="模版名称" required>
              <Input value={name} onChange={e => setName(e.target.value)} placeholder="请输入内容" style={{ width: 220 }} />
            </Form.Item>
            <Form.Item label="模版描述">
              <Input value={templateDesc} onChange={e => setTemplateDesc(e.target.value)} placeholder="请输入内容" style={{ width: 320 }} />
            </Form.Item>
            <Form.Item label="关联场景">
              <Select value={sceneId} onChange={v => setSceneId(v)} options={sceneOptions} style={{ width: 200 }} allowClear placeholder="请选择" loading={sceneLoading} />
            </Form.Item>
          </Form>
        </Card>
        <div style={{ 
          display: 'flex', 
          gap: 32, 
          height: 'calc(100vh - 280px)',
          overflow: 'hidden'
        }}>
          {/* 左侧内容区 */}
          <Card style={{ flex: 1, minWidth: 400, display: 'flex', flexDirection: 'column' }} bodyStyle={{ padding: 24, flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
            <div style={{ display: 'flex', alignItems: 'flex-start', marginBottom: 12 }}>
              <span style={{ fontWeight: 500, fontSize: 16, color: '#222', flexShrink: 0 }}>模版内容</span>
              <span style={{ 
                marginLeft: 16, 
                fontSize: 12, 
                color: '#888', 
                flex: 1,
                lineHeight: '1.5'
              }}>
                {/* eslint-disable-next-line no-template-curly-in-string */}
                使用 {'${变量}'} 进行变量设置，输入 `/` 符号可快速生成变量，
                使用 # 设置一级标题，## 二级标题，### 三级，以此类推
              </span>
            </div>
            <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
              <VariableTextArea
                value={content}
                onChange={setContent}
                onCompositionStart={() => setIsComposing(true)}
                onCompositionEnd={() => setIsComposing(false)}
                rows={18}
              />
            </div>
          </Card>
          {/* 右侧变量区 */}
          <Card style={{ flex: 1.2, minWidth: 450, display: 'flex', flexDirection: 'column' }} bodyStyle={{ padding: 16, flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
            <div style={{ marginBottom: 8, color: '#f5222d', fontSize: 13 }}>
              {/* eslint-disable-next-line no-template-curly-in-string */}
              变量区：内容中出现的 {'${变量}'} 会自动同步到这里
            </div>
            <div style={{ flex: 1, overflow: 'auto' }}>
              {variables.length === 0 ? (
                <Text type="secondary">暂无变量</Text>
              ) : (
                renderVariableRows(variables)
              )}
            </div>
          </Card>
        </div>
      </Spin>
      <div style={{ 
        position: 'fixed',
        bottom: 0,
        left: 0,
        width: '100%',
        background: '#fff',
        padding: '16px 32px',
        zIndex: 10
      }}>
        <div style={{ textAlign: 'right' }}>
          <Button style={{ marginRight: 16 }} loading={previewLoading} onClick={handlePreview}>预览</Button>
          <Button type="primary" loading={loading} onClick={handleSubmit}>
            发布
          </Button>
        </div>
      </div>
      <Modal
        title="预览结果"
        open={previewVisible}
        onCancel={() => setPreviewVisible(false)}
        footer={null}
        width={800}
      >
        <div style={{ maxHeight: '60vh', overflow: 'auto' }}>
          {previewResult.map((result, index) => (
            <div key={index} style={{ marginBottom: 16, whiteSpace: 'pre-wrap' }}>
              {result}
            </div>
          ))}
        </div>
      </Modal>
    </div>
  );
};

export default TemplateEdit; 